﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IPlugin;
using System.Threading;
using System.IO;
using System.Web;

namespace Plugin
{
    public class Plugin : IPlugin.IPlugin
    {
        public static bool aufbereitungLaeuft; //true wenn Karte (neu) eingelesen wird
        private string mapFileName = "map.osm";
        private string htmlFileName = "index.html";
        private StringBuilder stringBuilder;
        public Dictionary<string, HashSet<string>> streetCityDict { get; set; } //street, cities
        private MapReader mp;
        public string Name
        {
            get { return "GetNavi"; } //Ordner unter Plugins muss so heissen!!!
        }
        public string Version
        {
            get { return "1.0 Beta"; }
        }

        public Plugin()
        {
            aufbereitungLaeuft = false;
            streetCityDict = new Dictionary<string, HashSet<string>>();
            if (!Directory.Exists("Plugins\\" + Name))
            {
                Console.WriteLine("Error: Navigations-Plugin\n" + 
                    "Verzeichnis 'Plugins\\"+Name+"' konnte nicht gefunden werden.\nServer muss beendet werden.");
                Console.Read();
                Environment.Exit(0);
            }
            if (!File.Exists("Plugins\\" + Name + '\\' + mapFileName))
            {
                Console.WriteLine("Error: Navigations-Plugin\n" +
                    "Im Verzeichnis 'Plugins\\" + Name + "' wurde keine Map gefunden.\n" + 
                "Bitte stellen sie eine Map mit dem Dateinamen '"+mapFileName+"' bereit.\nServer muss beendet werden.");
                Console.Read();
                Environment.Exit(0);
            }
            if (!File.Exists("Plugins\\" + Name + '\\' + htmlFileName))
            {
                Console.WriteLine("Error: Navigations-Plugin\n" +
                    "Im Verzeichnis 'Plugins\\" + Name + "' wurde keine HTML-Datei gefunden.\n" +
                "Bitte stellen sie eine HTML-Datei mit dem Dateinamen '" + htmlFileName + "' bereit.\nServer muss beendet werden.");
                Console.Read();
                Environment.Exit(0);
            }

            FileStream fs = null;
            StreamReader sr = null;
            try
            {
                fs = File.OpenRead("Plugins\\" + Name + '\\' + htmlFileName);
                sr = new StreamReader(fs);
                stringBuilder = new StringBuilder("");
                while (!sr.EndOfStream)
                {
                    stringBuilder.Append(sr.ReadLine());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: Navigations-Plugin\nDetail: " + ex.Message);
                Console.Read();
                Environment.Exit(0);
            }
            finally
            {
                if (fs != null)
                    fs.Close();
                if (sr != null)
                    sr.Close();
            }
        }
        public Response ExecutePlugin(Request req)
        {
            if (aufbereitungLaeuft)
            {
                Response resp = new Response(req.getSocket());
                resp.StatusCode = 200;
                resp.StatusText = "OK";
                resp.ContentType = "text/html";
                resp.Data = "<html><body><h1>Sorry!</h1>" + 
                    "<p>Die Karte wird derzeit neu eingelesen. Das Plugin kann erst wieder Anfragen entgegen " + 
                    "nehmen, wenn der Vorgang abgeschlossen wurde.</p>";
                if (mp != null)
                {
                    resp.Data += "<p>" + mp.GetPercentOfFileStream() + " Prozent der Datei durchsucht...</p>";
                }
                resp.Data += "</body></html>";
                return resp;
            }
            else
            {
                Response resp = new Response(req.getSocket());
                if (req.ReqUrl.HasParameter)
                {
                    if (req.ReqUrl.ParameterList.Keys.Contains("action"))
                    {
                        if (req.ReqUrl.ParameterList["action"].Equals("refreshMap"))
                        {
                            aufbereitungLaeuft = true;
                            mp = new MapReader(Name, mapFileName, streetCityDict);
                            Thread t = new Thread(mp.Run);
                            t.Start();

                            resp.StatusCode = 200;
                            resp.StatusText = "OK";
                            resp.ContentType = "text/html";
                            resp.Data = "<html><body><p>Die Karte wird nun neu eingelesen...</p><br/><a href='/" + Name 
                                + "'>Zur&uuml;ck</a></body></html>";
                            return resp;
                        }
                    }
                }

                string htmlOutput = stringBuilder.ToString();

                if (req.ReqPostVars != null && req.ReqPostVars.ParameterList != null)
                {
                    if (req.ReqPostVars.ParameterList.ContainsKey("searchInputField"))
                    {
                        string street = req.ReqPostVars.ParameterList["searchInputField"];
                        //street = HttpUtility.UrlDecode(street, Encoding.GetEncoding(1252));
                        if (!street.Equals(""))
                        {
                            if (streetCityDict.Count == 0)
                            {
                                Console.WriteLine("street: '" + street + "'");
                                //Dictionary enthaelt noch keine Daten -> Error: Karte muss noch eingelesen werden
                                htmlOutput = htmlOutput.Replace("{Embedded-Sensor-Cloud-Content}", "<tr><td>Error: Karte muss zuerst eingelesen werden!</td></tr>");
                            }
                            else
                            {
                                if (streetCityDict.ContainsKey(street))
                                {
                                    HashSet<string> hs = streetCityDict[street];
                                    string result = "";
                                    for (int i = 0; i < hs.Count; i++)
                                    {
                                        if (i % 2 == 0)
                                            result += "<tr " + "class='style1'" + "><td>" + HttpUtility.HtmlEncode(hs.ElementAt(i)) + "</td></tr>";
                                        else
                                            result += "<tr " + "class='style2'" + "><td>" + HttpUtility.HtmlEncode(hs.ElementAt(i)) + "</td></tr>";
                                    }
                                    htmlOutput = htmlOutput.Replace("{Embedded-Sensor-Cloud-Content}", result);
                                }
                                else
                                {
                                    //Strasse nicht gefunden
                                    htmlOutput = htmlOutput.Replace("{Embedded-Sensor-Cloud-Content}", "<tr><td>Es konnte keine Stadt gefunden werden, in der es diese Strasse gibt.</td></tr>");
                                }
                            }
                        }
                        else
                        {
                            //Es wurde nichts ins Textfeld eingegeben
                            htmlOutput = htmlOutput.Replace("{Embedded-Sensor-Cloud-Content}", "");
                        }
                    }
                }
                else
                {
                    htmlOutput = htmlOutput.Replace("{Embedded-Sensor-Cloud-Content}", "");
                }

                resp.StatusCode = 200;
                resp.StatusText = "OK";
                resp.ContentType = "text/html";
                resp.Data = htmlOutput;
                return resp;
            }
        }
    }
}
